﻿using System;
using System.Runtime.Serialization;
using Flatland.GeneticProgramming.SyntaxTree;

/**
* 
* Copyright (c) 2012 Anders Høst Kjærgaard | ahkj@itu.dk
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, 
* including without limitation the rights to use, copy, modify, merge, publish, distribute, 
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial 
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Flatland.GeneticProgramming.CoreTypes {
    /// <summary>
    /// Datacontainer with a gene and its related data.
    /// </summary>
    [Serializable]
    public class Report : ICloneable, ISerializable {

        /// <summary>
        /// The GenoType.
        /// </summary>
        public GenoType GenoType { get; set; }

        /// <summary>
        /// Fitness of the GenoType
        /// </summary>
        public double Fitness { get; set; }

        /// <summary>
        /// PrimitiveSet that contains PrimitiveSet material that the GenoType can be evolved with.
        /// </summary>
        public PrimitiveSet PrimitiveSet { get; set; }

        /// <summary>
        /// Generation relative to a GP run where this GenoType was created.
        /// </summary>
        public int Generation { get; set; }

        /// <summary>
        /// Output path if source code is written to file.
        /// </summary>
        public String FilePath { get; set; }

        /// <summary>
        /// Public constructor
        /// </summary>
        public Report() {
        }

        /// <summary>
        /// Clone this GenoType.
        /// </summary>
        /// <returns></returns>
        public object Clone() {
            Report clone = new Report{
                Fitness = Fitness,
                FilePath = FilePath,
                PrimitiveSet = PrimitiveSet,
            };
            clone.GenoType = (GenoType)GenoType.Clone();
            clone.GenoType.Tree = (Tree) GenoType.Tree.Clone();
            return clone;
        }

        /// <summary>
        /// Deserialize constructor
        /// </summary>
        /// <param name="info"></param>
        /// <param name="context"></param>
        public Report(SerializationInfo info, StreamingContext context)
        {
            GenoType = (GenoType) info.GetValue("GenoType", typeof (GenoType));
            GenoType.Tree = (Tree)info.GetValue("Tree", typeof(Tree));
            FilePath = (String)info.GetValue("FilePath", typeof(String));
            Fitness = (int)info.GetValue("Fitness", typeof(int));
            PrimitiveSet = (PrimitiveSet)info.GetValue("PrimitiveSet", typeof(PrimitiveSet));
            Generation = (int)info.GetValue("Generation", typeof(int));
        }

        /// <summary>
        /// Serialize.
        /// </summary>
        /// <param name="info"></param>
        /// <param name="context"></param>
        public void GetObjectData(SerializationInfo info, StreamingContext context) {
            info.AddValue("GenoType", GenoType);
            info.AddValue("Tree", GenoType.Tree);
            info.AddValue("FilePath", FilePath);
            info.AddValue("Fitness", Fitness);
            info.AddValue("PrimitiveSet", PrimitiveSet);
            info.AddValue("Generation", Generation);
        }

        public override string ToString() {
            return "File path: " + FilePath + "\nFitness: " + Fitness;
        }
    }
}